console.log(a);
var a = 1;
若要用一段程式碼來講 Hoisting,我想這段程式應該就會是Hoisting最佳的解釋了吧。
在剛學程式時,一直覺得這段 code 會顯示出 Uncaught ReferenceError: a is not defined,但實際運行上他卻只會出現 undefined ,直到後來才知道原來他就是所謂的 Hoisting。
那 Hoisting 到底是什麼呢?
Hoisting 是指 一種把宣告提升到其區域內最頂端的內部行為
,不過提升行為只針對宣告的部分,對於值的設定,並沒有跟著提升。
說了這麼多,還是用程式碼來示範給大家看吧!
// 將變數宣告提升
var x = 1;
(function() {
console.log(x); //undefined
var x = 10;
})();
console.log(x); // 1;
實際上,程式的執行過程是
var x = 1;
(function() {
var x;
console.log(x); //undefined
x = 10;
})();
console.log(x); // 1;
也就是上述的,將宣告提升到區域的最頂部。
各位是不是對於 Hoisting 好像有些了解但又不是很清楚呢?
沒關係,那我們就再來一段程式碼吧!
var a = 1;
function isHoisting() {
if( !a ) {
var a = 2;
}
console.log(a);
})
isHoisting();
聰明的同學們,你們認為 a 顯示出來的會是 A or B 呢?
(A) 1
(B) 2
沒錯,答案就是 (B) 哦,至於為什麼呢?
// 實際程式執行過程
var a = 1;
function isHoisting() {
var a;
if( !a ) {
a = 2;
}
console.log(a);
})
isHoisting();
就是因為 Hoisting 的緣故呢!
這邊補充一個小知識,有些人說 ES6 的 let 和 const 並沒有 Hoisting,
這個說法其實是有一些爭議的哦,
請看一下程式碼
console.log(a);
let a = 1;
若是拿這段程式碼執行,會出現 Uncaught ReferenceError: Cannot access 'a' before initialization
錯誤,這也就是為什麼他們會說 ES6 的 let 和 const 並沒有 Hoisting 的原因,但請看下方這段程式碼
let a = 2;
(function() {
console.log(a);
let a = 10;
})();
這段程式碼能證明說 let 其實是有 Hoisting 的特性,但是其並無法操作,所以我們稱被提升至頂部的變數宣告
到使用該變數的這段,為死區( Dead Zone )。
我們換句話說,如果我們在死區內使用該變數,則 JavaScript 就會報錯。
今天身體一直不太舒服,打完這篇文章在廁所待了快一個小時,差點就來不及發佈了
參考資料:
Tommy - 深入 JavaScript 核心課程
TechBridge 技術共筆部落格 - 我知道你懂 hoisting,可是你了解到多深?